package org.jeecg.modules.fk.service;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import org.jeecg.modules.fk.mapper.auto.model.*;
import org.jeecg.modules.fk.mapper.manual.model.riskprocesslist.*;
import org.jeecg.modules.fk.mapper.manual.model.RiskReportListExt;
import org.jeecg.modules.fk.constant.ReportStatusEnum;
import org.jeecg.modules.fk.constant.ZbTypeEnum;
import org.jeecg.modules.fk.vo.inner.req.RiskProcessReqDTO;
import org.jeecg.modules.fk.vo.req.*;
import org.jeecg.modules.fk.repository.FkDaoRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;

@Slf4j
@Service
public class RiskProcessService {

    @Autowired
    private FkDaoRepository daoRepository;

    public RiskProcessList riskProcess(RiskProcessReqDTO dto) {
        RiskProcessListKey key = new RiskProcessListKey();
        BeanUtils.copyProperties(dto, key);
        key.setYwdlDm(dto.getZbType().toString());

        RiskProcessList riskProcess = this.daoRepository.getRiskProcessListMapper().selectByPrimaryKey(key);

        return riskProcess;
    }

    public Object getFpRiskReportList(FpRiskReportListReqDTO dto) {
        String nsrsbh = dto.getNsrsbh();
        String ywdlDm = ZbTypeEnum.ZZSFP.toString();
        RiskReportListExt request = new RiskReportListExt();
        request.setNsrsbh(nsrsbh);
        request.setYwdlDm(ywdlDm);
        request.setSize(dto.getSize());

        RiskProcessList lastRiskReport = this.daoRepository.getRiskProcessListExtMapper().getLastSkssqRiskProcessRecord(ywdlDm, nsrsbh);
        if (false == ObjectUtils.isEmpty(lastRiskReport)) {
            // 税款所属期止 - 税款所属期起 月报还是季报
            long months = DateUtil.betweenMonth(lastRiskReport.getSkssqq(), lastRiskReport.getSkssqz(), true);

            if (2L == months) {
                List<QuarterRiskReportListRespDTO> zzsfpQuarterReportList = this.daoRepository.getRiskProcessListExtMapper().getQuarterRiskReportList(request);
                for (QuarterRiskReportListRespDTO quarterRiskReportListRespDTO : zzsfpQuarterReportList) {
                    getMsgReportList(nsrsbh, quarterRiskReportListRespDTO, ywdlDm);

                    // 生成成功,加结论
                    if ("GENERATED".equals(quarterRiskReportListRespDTO.getReportState())) {
                        String skssqq = DateUtil.format(quarterRiskReportListRespDTO.getSkssqq(), DatePattern.NORM_DATE_PATTERN);
                        String skssqz = DateUtil.format(quarterRiskReportListRespDTO.getSkssqz(), DatePattern.NORM_DATE_PATTERN);

                        // 结论、测检得分
                        RiskReportLevel risk = this.daoRepository.getRiskReportLevelExtMapper().getRiskReportLevelByKey(ywdlDm, nsrsbh, skssqq, skssqz);
                        if (null != risk) {
                            JieLunRespDTO jieLun = new JieLunRespDTO();
                            BeanUtils.copyProperties(risk, jieLun);

                            quarterRiskReportListRespDTO.setJieLun(jieLun);
                        }
                    }
                }

                return zzsfpQuarterReportList;
            }
        }

        List<MonthRiskReportListRespDTO> zzsfpMonthRiskReportList = this.daoRepository.getRiskProcessListExtMapper().getMonthRiskReportList(request);
        for (MonthRiskReportListRespDTO monthRiskReportListRespDTO : zzsfpMonthRiskReportList) {
            getMsgReportList(nsrsbh, monthRiskReportListRespDTO, ywdlDm);
            //加结论信息
            setJieLun(nsrsbh, ywdlDm, monthRiskReportListRespDTO);
        }
        return zzsfpMonthRiskReportList;
    }

    private void setJieLun(String nsrsbh, String reportType, MonthRiskReportListRespDTO monthRiskReportListRespDTO) {
        // 生成成功,加结论
        if ("GENERATED".equals(monthRiskReportListRespDTO.getReportState())) {
            String skssqq = DateUtil.format(monthRiskReportListRespDTO.getSkssqq(), DatePattern.NORM_DATE_PATTERN);
            String skssqz = DateUtil.format(monthRiskReportListRespDTO.getSkssqz(), DatePattern.NORM_DATE_PATTERN);
            // 结论、测检得分
            RiskReportLevel risk = this.daoRepository.getRiskReportLevelExtMapper().getRiskReportLevelByKey(reportType, nsrsbh, skssqq, skssqz);
            if (null != risk) {
                JieLunRespDTO jieLun = new JieLunRespDTO();
                BeanUtils.copyProperties(risk, jieLun);

                monthRiskReportListRespDTO.setJieLun(jieLun);
            }
        }
    }

    private void getMsgReportList(String nsrsbh, RiskReportListRespDTO riskReportListRespDTO, String type) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date skssqq = riskReportListRespDTO.getSkssqq();
        Date skssqz = riskReportListRespDTO.getSkssqz();
        Calendar ca = Calendar.getInstance();
        ca.setTime(skssqq);
        int skssqqY = ca.get(Calendar.YEAR);

        MonthRiskReportListRespDTO respDTO = this.daoRepository.getRiskProcessListStateRecordExtMapper().getMonthRiskReportStateList(type, nsrsbh,
                sdf.format(skssqq), sdf.format(skssqz), null);
        log.info("【查询报告(当前),属期:{}至{}】返回数据:{}", sdf.format(skssqq), sdf.format(skssqz), JSON.toJSON(respDTO));
        if (respDTO == null) {
            if (skssqqY == LocalDate.now().getYear()) {
                //取今年01-01
                respDTO = this.daoRepository.getRiskProcessListStateRecordExtMapper().getMonthRiskReportStateList(type, nsrsbh,
                        LocalDate.now().getYear() + "-01-01", null, ReportStatusEnum.FAIL.toString());
                log.info("【查询报告(大范围),属期:{}至{}】返回数据:{}", LocalDate.now().getYear() + "-01-01"
                        , LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).toString(), JSON.toJSON(respDTO));
            } else {
                respDTO = this.daoRepository.getRiskProcessListStateRecordExtMapper().getMonthRiskReportStateList(type, nsrsbh,
                        skssqqY + "-01-01", skssqqY + "-12-31", ReportStatusEnum.FAIL.toString());
                log.info("【查询报告(大范围),属期:{}至{}】返回数据:{}", skssqqY + "-01-01", skssqqY + "-12-31", JSON.toJSON(respDTO));
            }
            if (respDTO != null) {
                riskReportListRespDTO.setCreateDate(respDTO.getCreateDate());
            }
        }
        if (respDTO != null) {
            riskReportListRespDTO.setReportState(respDTO.getReportState());

            //失败原因千奇百怪，用户看不懂，统一处理后，再返回给前端展示
            String msg = respDTO.getMsg();
            if (null != msg) {
                if (msg.contains("登录失败")) {
                    msg = "登录失败，请重新绑定企业再试！";
                    riskReportListRespDTO.setMsg(msg);
                    return;
                }

                if (msg.contains("密码错误")) {
                    msg = "密码错误，请重新绑定企业再试！";
                    riskReportListRespDTO.setMsg(msg);
                    return;
                }

                if (msg.contains("无申报记录")) {
                    msg = "您的企业本属期无申报记录，请核实！";
                    riskReportListRespDTO.setMsg(msg);
                    return;
                }

                msg = msg.replaceAll("<kfpt>", "");
                if (msg.matches("^[a-z,A-Z]{1}[\\s\\S]*$")) {
                    msg = "报告生成失败，请稍后再试！";
                    riskReportListRespDTO.setMsg(msg);
                    return;
                }

                //未生成的也把提示语返回
                riskReportListRespDTO.setMsg(msg);
            }
        }

    }

    public Object getZzsRiskReportList(ZzsRiskReportListReqDTO dto) {
        RiskProcessList lastRiskReport = this.daoRepository.getRiskProcessListExtMapper().getLastSkssqRiskProcessRecord(ZbTypeEnum.ZZS.toString(), dto.getNsrsbh());

        String nsrsbh = dto.getNsrsbh();
        if (null != lastRiskReport) {
            // 税款所属期止 - 税款所属期起 月报还是季报
            long m = DateUtil.betweenMonth(lastRiskReport.getSkssqq(), lastRiskReport.getSkssqz(), true);
            switch (String.valueOf(m)) {
                case "0":
                    // 月报
                    return getZZSMonthReportList(nsrsbh, ZbTypeEnum.ZZS, dto.getSize());
                case "2":
                    // 季报
                    return getZZSQuarterReportList(dto, nsrsbh);
                default:
                    return getZZSMonthReportList(nsrsbh, ZbTypeEnum.ZZS, dto.getSize());
            }
        }

        return getZZSMonthReportList(nsrsbh, ZbTypeEnum.ZZS, dto.getSize());
    }

    private Object getZZSQuarterReportList(ZzsRiskReportListReqDTO dto, String nsrsbh) {
        String ywdlDm = ZbTypeEnum.ZZS.toString();
        RiskReportListExt request = new RiskReportListExt();
        request.setNsrsbh(nsrsbh);
        request.setYwdlDm(ywdlDm);
        request.setSize(dto.getSize());
        //季报
        List<QuarterRiskReportListRespDTO> zzsQuarterReportList = this.daoRepository.getRiskProcessListExtMapper().getQuarterRiskReportList(request);
        for (QuarterRiskReportListRespDTO quarterRiskReportListRespDTO : zzsQuarterReportList) {
            getMsgReportList(nsrsbh, quarterRiskReportListRespDTO, ZbTypeEnum.ZZS.toString());

            // 生成成功,加结论
            if ("GENERATED".equals(quarterRiskReportListRespDTO.getReportState())) {
                String skssqq = DateUtil.format(quarterRiskReportListRespDTO.getSkssqq(), DatePattern.NORM_DATE_PATTERN);
                String skssqz = DateUtil.format(quarterRiskReportListRespDTO.getSkssqz(), DatePattern.NORM_DATE_PATTERN);
                // 结论、测检得分
                RiskReportLevel risk = this.daoRepository.getRiskReportLevelExtMapper().getRiskReportLevelByKey(ZbTypeEnum.ZZS.toString(), nsrsbh, skssqq, skssqz);
                if (null != risk) {
                    JieLunRespDTO jieLun = new JieLunRespDTO();
                    BeanUtils.copyProperties(risk, jieLun);

                    quarterRiskReportListRespDTO.setJieLun(jieLun);
                }
            }
        }
        return zzsQuarterReportList;
    }

    private Object getZZSMonthReportList(String nsrsbh, ZbTypeEnum zzs, Integer size) {
        String ywdlDm = ZbTypeEnum.ZZS.toString();
        RiskReportListExt request = new RiskReportListExt();
        request.setNsrsbh(nsrsbh);
        request.setYwdlDm(ywdlDm);
        request.setSize(size);
        //月报
        List<MonthRiskReportListRespDTO> zzsMonthReportList = this.daoRepository.getRiskProcessListExtMapper().getMonthRiskReportList(request);
        for (MonthRiskReportListRespDTO monthRiskReportListRespDTO : zzsMonthReportList) {
            getMsgReportList(nsrsbh, monthRiskReportListRespDTO, zzs.toString());

            // 生成成功,加结论
            setJieLun(nsrsbh, zzs.toString(), monthRiskReportListRespDTO);
        }
        return zzsMonthReportList;
    }

    public int createRiskReportProcessRecord(RiskProcessListRecord dto) {
        int result = 0;
        RiskProcessListRecordKey key = new RiskProcessListRecordKey();
        BeanUtils.copyProperties(dto, key);

        RiskProcessListRecord record = this.daoRepository.getRiskProcessListRecordMapper().selectByPrimaryKey(key);

        if (null == record) {
            dto.setCreateDate(new Date());
            dto.setUpdateDate(new Date());

            result = this.daoRepository.getRiskProcessListRecordMapper().insert(dto);
        } else {
            dto.setUpdateDate(new Date());

            result = this.daoRepository.getRiskProcessListRecordMapper().updateByPrimaryKeySelective(dto);
        }

        return result;
    }

    public AllTypeRiskReportRespDTO getAllTypeLastReport(AllTypeRiskReportReqDTO dto) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        AllTypeRiskReportRespDTO result = new AllTypeRiskReportRespDTO();

        RiskProcessListKey key = new RiskProcessListKey();
        key.setNsrsbh(dto.getNsrsbh());

        Date skssqq = null;
        Date skssqz = null;
        Date yearSkssqq = null;
        Date yearSkssqz = null;
        try {
            skssqq = sdf.parse(dto.getSkssqq());
            skssqz = sdf.parse(dto.getSkssqz());

            yearSkssqq = sdf.parse(dto.getYearSkssqq());
            yearSkssqz = sdf.parse(dto.getYearSkssqz());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        key.setSkssqq(skssqq);
        key.setSkssqz(skssqz);

        key.setYwdlDm(ZbTypeEnum.ZZS.toString());
        RiskProcessList zzs = this.daoRepository.getRiskProcessListMapper().selectByPrimaryKey(key);
        RiskReportListRespDTO zzsfx = new RiskReportListRespDTO();
        setReportState(dto, zzs, zzsfx, skssqq, skssqz);

        result.setZzsfx(zzsfx);

        key.setYwdlDm(ZbTypeEnum.ZZSFP.toString());
        RiskProcessList fp = this.daoRepository.getRiskProcessListMapper().selectByPrimaryKey(key);
        RiskReportListRespDTO fpfx = new RiskReportListRespDTO();
        setReportState(dto, fp, fpfx, skssqq, skssqz);

        result.setFpfx(fpfx);

        key.setSkssqq(yearSkssqq);
        key.setSkssqz(yearSkssqz);
        key.setYwdlDm(ZbTypeEnum.QYSDS.toString());
        RiskProcessList qysds = this.daoRepository.getRiskProcessListMapper().selectByPrimaryKey(key);
        RiskReportListRespDTO qysdsfx = new RiskReportListRespDTO();
        setReportState(dto, qysds, qysdsfx, yearSkssqq, yearSkssqz);

        result.setQysdsfx(qysdsfx);

        key.setSkssqq(yearSkssqq);
        key.setSkssqz(yearSkssqz);
        key.setYwdlDm(ZbTypeEnum.CWBB.toString());
        RiskProcessList cwbb = this.daoRepository.getRiskProcessListMapper().selectByPrimaryKey(key);
        RiskReportListRespDTO cwbbfx = new RiskReportListRespDTO();
        setReportState(dto, cwbb, cwbbfx, yearSkssqq, yearSkssqz);

        result.setCwbbfx(cwbbfx);

        return result;
    }

    private void setReportState(AllTypeRiskReportReqDTO dto, RiskProcessList process, RiskReportListRespDTO zzsfx, Date skssqq, Date skssqz) {
        zzsfx.setSkssqq(skssqq);
        zzsfx.setSkssqz(skssqz);
        if (process != null) {
            zzsfx.setCreateDate(process.getUpdateDate());
            zzsfx.setReportState(ReportStatusEnum.GENERATED.toString());
        }
    }

    public Object getQysdsRiskReportList(QysdsRiskReportListReqDTO dto) {
        String nsrsbh = dto.getNsrsbh();
        String ywdlDm = ZbTypeEnum.QYSDS.toString();

        RiskReportListExt request = new RiskReportListExt();
        request.setNsrsbh(nsrsbh);
        request.setYwdlDm(ywdlDm);

        // 原始代码仅开放一年数据，暂时开放2019年度数据
        Integer size = dto.getSize();
        size = 2;
        request.setSize(size);

        List<YearRiskReportListRespDTO> result = this.daoRepository.getRiskProcessListExtMapper().getYearRiskReportList(request);

        for (YearRiskReportListRespDTO report : result) {
            //生成功，设结论
            if ("GENERATED".equals(report.getReportState())) {
                String skssqq = DateUtil.format(report.getSkssqq(), DatePattern.NORM_DATE_PATTERN);
                String skssqz = DateUtil.format(report.getSkssqz(), DatePattern.NORM_DATE_PATTERN);
                // 结论、测检得分
                RiskReportLevel risk = this.daoRepository.getRiskReportLevelExtMapper().getRiskReportLevelByKey(ywdlDm, nsrsbh, skssqq, skssqz);
                if (null != risk) {
                    JieLunRespDTO jieLun = new JieLunRespDTO();
                    BeanUtils.copyProperties(risk, jieLun);

                    report.setJieLun(jieLun);
                }
            }
        }
        return result;
    }

    /**
     * 根据纳税人识号返回财务风险报告列表
     *
     * @param dto 财务风险报告列表DTO对象
     *
     * @return 财务风险报告列表
     */
    public Object getFinanceRiskReportList(FinanceRiskReportListReqDTO dto) {
        String nsrsbh = dto.getNsrsbh();
        String ywdlDm = ZbTypeEnum.CWBB.toString();

        RiskReportListExt request = new RiskReportListExt();
        request.setNsrsbh(nsrsbh);
        request.setYwdlDm(ywdlDm);
//        request.setSize(dto.getSize());
        request.setSize(1);

        List<YearRiskReportListRespDTO> result = this.daoRepository.getRiskProcessListExtMapper().getYearRiskReportList(request);

        for (YearRiskReportListRespDTO report : result) {
            //生成功，设结论
            if ("GENERATED".equals(report.getReportState())) {
                String skssqq = DateUtil.format(report.getSkssqq(), DatePattern.NORM_DATE_PATTERN);
                String skssqz = DateUtil.format(report.getSkssqz(), DatePattern.NORM_DATE_PATTERN);

//                // 结论、测检得分
//                RiskReportLevel risk = this.daoRepository.getRiskReportLevelExtMapper().getRiskReportLevelByKey(ywdlDm, nsrsbh, skssqq, skssqz);
//                if (null != risk) {
//                    JieLunRespDTO jieLun = new JieLunRespDTO();
//                    BeanUtils.copyProperties(risk, jieLun);
//
//                    report.setJieLun(jieLun);
//                }
            }
        }

        return result;
    }

    /**
     * 根据纳税人识号及业务大类代码返回风险报告列表
     *
     * @param dto 风险报告列表DTO对象
     *
     * @return 风险报告列表
     */
    public List<RiskReportListRespExtDTO> getCwbbRiskReportList(RiskReportListReqDTO dto) {
        String nsrsbh = dto.getNsrsbh();
        String ywdlDm = dto.getYwdlDm();
        String areaCode = dto.getAreaCode();

        RiskReportListExt request = new RiskReportListExt();
        request.setNsrsbh(nsrsbh);
        request.setYwdlDm(ywdlDm);

        List<RiskReportListRespExtDTO> riskReportListRespExtDTOList = this.daoRepository.getRiskProcessListExtMapper().getRiskReportListExt(request);

        Map<String, List<RiskReportListRespExtDTO>> riskReportListRespExtDTO2Map = riskReportListRespExtDTOList.stream()
                .collect(groupingBy(RiskReportListRespExtDTO::getCycleformat));

        if (ObjectUtils.isEmpty(riskReportListRespExtDTO2Map)) {
            return riskReportListRespExtDTOList;
        }

        List<RiskReportListRespExtDTO> customizedData = new ArrayList<>();

        boolean existYearMonthData = false;
        List<RiskReportListRespExtDTO> yearMonthData = riskReportListRespExtDTO2Map.get("YYYYMM");
        if (!ObjectUtils.isEmpty(yearMonthData)) {
            existYearMonthData = yearMonthData.stream().anyMatch(d -> "GENERATED".equals(d.getState()));
        }

        boolean existYearQuarterData = false;
        List<RiskReportListRespExtDTO> yearQuarterData = riskReportListRespExtDTO2Map.get("YYYYQQ");
        if (!ObjectUtils.isEmpty(yearQuarterData)) {
            existYearQuarterData = yearQuarterData.stream().anyMatch(d -> "GENERATED".equals(d.getState()));
        }

        if (true == existYearMonthData) {
            customizedData.addAll(yearMonthData);
        }

        if (false == existYearMonthData && true == existYearQuarterData) {
            customizedData.addAll(yearQuarterData);
        }

        if (false == existYearMonthData && false == existYearQuarterData) {
            customizedData.addAll(yearQuarterData);

            List<String> specialAreaList = Arrays.asList("520000", "630000");
            if (true == specialAreaList.contains(areaCode)) {
                customizedData.clear();
                customizedData.addAll(yearMonthData);
            }
        }

        List<RiskReportListRespExtDTO> yearData = riskReportListRespExtDTO2Map.get("YYYY");
        if (!ObjectUtils.isEmpty(yearData)) {
            customizedData.addAll(yearData);
        }

        if (!ObjectUtils.isEmpty(yearData)) {
            riskReportListRespExtDTOList = customizedData;
        }

        riskReportListRespExtDTOList.forEach(r -> {
            String msg = r.getMsg();
            r.setRawMsg(msg);

            if (ObjectUtils.isEmpty(msg)) {
                return;
            }

            if (msg.contains("登录失败")) {
                msg = "登录失败，请重新绑定企业再试！";
            }

            if (msg.contains("密码错误")) {
                msg = "密码错误，请重新绑定企业再试！";
            }

            if (msg.contains("无申报记录")) {
                msg = "您的企业本属期无申报记录，请核实！";
            }

            msg = msg.replaceAll("<kfpt>", "");
            if (msg.matches("^[a-z,A-Z]{1}[\\s\\S]*$")) {
                msg = "报告生成失败，请稍后再试！";
            }

            r.setMsg(msg);
        });

        if ("CWBB".equalsIgnoreCase(ywdlDm)) {
            return riskReportListRespExtDTOList;
        }

        for (RiskReportListRespExtDTO riskReportListRespExtDTO : riskReportListRespExtDTOList) {

            this.setJieLunExt(nsrsbh, ywdlDm, riskReportListRespExtDTO);
//            //生成功，设结论
//            if ("GENERATED".equals(riskReportListRespExtDTO.getReportState())) {
//                String skssqq = DateUtil.format(riskReportListRespExtDTO.getSkssqq(), DatePattern.NORM_DATE_PATTERN);
//                String skssqz = DateUtil.format(riskReportListRespExtDTO.getSkssqz(), DatePattern.NORM_DATE_PATTERN);
//
//                // 结论、测检得分
//                RiskReportLevel risk = this.daoRepository.getRiskReportLevelExtMapper().getRiskReportLevelByKey(ywdlDm, nsrsbh, skssqq, skssqz);
//                if (null != risk) {
//                    JieLunRespDTO jieLun = new JieLunRespDTO();
//                    BeanUtils.copyProperties(risk, jieLun);
//
//                    riskReportListRespExtDTO.setJieLun(jieLun);
//                }
//            }
        }

        return riskReportListRespExtDTOList;
    }

    /**
     * 设置结论
     *
     * @param nsrsbh                纳税人识别号
     * @param reportType            报表类型
     * @param riskReportListRespDTO 风险报告列表DTO对象
     * @param <T>
     */
    private <T extends RiskReportListRespDTO> void setJieLunExt(String nsrsbh, String reportType, T riskReportListRespDTO) {
        // 生成成功,加结论
        if (false == "GENERATED".equals(riskReportListRespDTO.getReportState())) {
            return;
        }

        String skssqq = DateUtil.format(riskReportListRespDTO.getSkssqq(), DatePattern.NORM_DATE_PATTERN);
        String skssqz = DateUtil.format(riskReportListRespDTO.getSkssqz(), DatePattern.NORM_DATE_PATTERN);

        // 结论、测检得分
        RiskReportLevel risk = this.daoRepository.getRiskReportLevelExtMapper().
                getRiskReportLevelByKey(reportType, nsrsbh, skssqq, skssqz);
        if (null != risk) {
            JieLunRespDTO jieLun = new JieLunRespDTO();
            BeanUtils.copyProperties(risk, jieLun);

            riskReportListRespDTO.setJieLun(jieLun);
        }
    }

    /**
     * 获取小规模风险报告列表
     *
     * @param dto 小规模风险报告列表DTO对象
     *
     * @return 风险报告列表
     */
    public List<RiskReportListRespExtDTO> getXgmRiskReportList(XgmRiskReportListReqDTO dto) {
        String nsrsbh = dto.getNsrsbh();
        String ywdlDm = dto.getYwdlDm();
        Integer size = dto.getSize();

        RiskReportListExt request = new RiskReportListExt();
        request.setNsrsbh(nsrsbh);
        request.setYwdlDm(ywdlDm);
        request.setSize(size);

        List<RiskReportListRespExtDTO> riskReportListRespExtDTOList = this.daoRepository.getRiskProcessListExtMapper()
                .getMonthAndQuarterRiskReportList(request);

        if (ObjectUtils.isEmpty(riskReportListRespExtDTOList)) {
            return riskReportListRespExtDTOList;
        }

        List<RiskReportListRespExtDTO> monthDataList = riskReportListRespExtDTOList.stream()
                .filter(r -> "YYYYMM".equals(r.getCycleformat()) && "GENERATED".equals(r.getState()))
                .collect(toList());

        boolean hasMonthData = monthDataList.size() > 0;
        if (false == hasMonthData) {
            riskReportListRespExtDTOList = riskReportListRespExtDTOList.stream()
                    .filter(r -> "YYYYQQ".equals(r.getCycleformat()))
                    .collect(toList());
        }

//        RiskReportListRespExtDTO latestRiskReportListRespExtDTO = Collections.max(riskReportListRespExtDTOList.stream()
//                .filter(r -> "GENERATED".equals(r.getState()))
//                .collect(toList()), Comparator.comparing(RiskReportListRespExtDTO::getSkssqz).reversed()
//                .thenComparing(RiskReportListRespExtDTO::getSkssqq).reversed());

        RiskReportListRespExtDTO latestRiskReportListRespExtDTO = riskReportListRespExtDTOList.stream()
                .filter(r -> "GENERATED".equals(r.getState()))
                .max(Comparator.comparing(RiskReportListRespExtDTO::getSkssqz).reversed()
                        .thenComparing(RiskReportListRespExtDTO::getSkssqq).reversed())
                .orElse(null);

        if (true == ObjectUtils.isEmpty(latestRiskReportListRespExtDTO)) {
            riskReportListRespExtDTOList = riskReportListRespExtDTOList.stream()
                    .filter(r -> "YYYYQQ".equals(r.getCycleformat()))
                    .collect(toList());
        }

        List<RiskReportListRespExtDTO> excludedQuarterDataList = riskReportListRespExtDTOList.stream()
                .filter(r -> ("YYYYQQ".equals(r.getCycleformat()) &&
                        monthDataList.stream().anyMatch(m -> m.getSkssqq().compareTo(r.getSkssqq()) >= 0 &&
                                m.getSkssqz().compareTo(r.getSkssqz()) <= 0)) ||
                        (!ObjectUtils.isEmpty(latestRiskReportListRespExtDTO) &&
                                "YYYYMM".equals(latestRiskReportListRespExtDTO.getCycleformat()) &&
                                r.getSkssqq().compareTo(latestRiskReportListRespExtDTO.getSkssqz()) >= 0))
                .collect(toList());

        riskReportListRespExtDTOList = riskReportListRespExtDTOList.stream()
                .filter(r -> ("YYYYMM".equals(r.getCycleformat()) &&
                        excludedQuarterDataList.stream().anyMatch(e -> r.getSkssqq().compareTo(e.getSkssqq()) >= 0 &&
                                r.getSkssqz().compareTo(e.getSkssqz()) <= 0)) ||
                        ("YYYYQQ".equals(r.getCycleformat()) &&
                                excludedQuarterDataList.stream().noneMatch(e -> e.getSkssq().equals(r.getSkssq()))))
                .collect(toList());

//        riskReportListRespExtDTOList = riskReportListRespExtDTOList.stream()
//                .filter(r -> !ObjectUtils.isEmpty(r.getState()))
//                .collect(toList());
//
//        if (ObjectUtils.isEmpty(riskReportListRespExtDTOList)) {
//            return riskReportListRespExtDTOList;
//        }

//        boolean hasMonthData = riskReportListRespExtDTOList.stream()
//                .anyMatch(r -> "YYYYMM".equals(r.getCycleformat()) && !ObjectUtils.isEmpty(r.getState()));
//
//        boolean hasQuarterData = riskReportListRespExtDTOList.stream()
//                .anyMatch(r -> "YYYYQQ".equals(r.getCycleformat()) && !ObjectUtils.isEmpty(r.getState()));
//
//        boolean hasNotData = !hasMonthData && !hasQuarterData;
//        if (true == hasNotData || (!hasMonthData && hasQuarterData)) {
//            riskReportListRespExtDTOList = riskReportListRespExtDTOList.stream()
//                    .filter(r -> "YYYYQQ".equals(r.getCycleformat()))
//                    .collect(toList());
//        }
//
//        if (hasMonthData && !hasQuarterData) {
//            riskReportListRespExtDTOList = riskReportListRespExtDTOList.stream()
//                    .filter(r -> "YYYYMM".equals(r.getCycleformat()))
//                    .collect(toList());
//        }

        final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        riskReportListRespExtDTOList.forEach(r -> {
            Date skssqq = r.getSkssqq();
            Date skssqz = r.getSkssqz();
            String formatSkssqq = simpleDateFormat.format(skssqq);
            String formatSkssqz = simpleDateFormat.format(skssqz);
            Calendar ca = Calendar.getInstance();
            ca.setTime(skssqq);
            int skssqqY = ca.get(Calendar.YEAR);

            MonthRiskReportListRespDTO riskReportStateList = this.daoRepository.getRiskProcessListStateRecordExtMapper()
                    .getMonthRiskReportStateList(ywdlDm, nsrsbh, formatSkssqq, formatSkssqz, null);
            log.info("【查询报告(当前),属期:{}至{}】返回数据:{}", formatSkssqq, formatSkssqz, JSON.toJSON(riskReportStateList));
            if (riskReportStateList == null) {
                if (skssqqY == LocalDate.now().getYear()) {
                    //取今年01-01
                    riskReportStateList = this.daoRepository.getRiskProcessListStateRecordExtMapper().getMonthRiskReportStateList(ywdlDm, nsrsbh,
                            LocalDate.now().getYear() + "-01-01", null, ReportStatusEnum.FAIL.toString());
                    log.info("【查询报告(大范围),属期:{}至{}】返回数据:{}", LocalDate.now().getYear() + "-01-01"
                            , LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).toString(), JSON.toJSON(riskReportStateList));
                } else {
                    riskReportStateList = this.daoRepository.getRiskProcessListStateRecordExtMapper().getMonthRiskReportStateList(ywdlDm, nsrsbh,
                            skssqqY + "-01-01", skssqqY + "-12-31", ReportStatusEnum.FAIL.toString());
                    log.info("【查询报告(大范围),属期:{}至{}】返回数据:{}", skssqqY + "-01-01", skssqqY + "-12-31", JSON.toJSON(riskReportStateList));
                }

                if (riskReportStateList != null) {
                    r.setCreateDate(riskReportStateList.getCreateDate());
                }
            }

            if (riskReportStateList != null) {
                r.setReportState(riskReportStateList.getReportState());

                //失败原因千奇百怪，用户看不懂，统一处理后，再返回给前端展示
                String msg = riskReportStateList.getMsg();
                if (null != msg) {
                    if (msg.contains("登录失败")) {
                        msg = "登录失败，请重新绑定企业再试！";
                        r.setMsg(msg);
                        return;
                    }

                    if (msg.contains("密码错误")) {
                        msg = "密码错误，请重新绑定企业再试！";
                        r.setMsg(msg);
                        return;
                    }

                    if (msg.contains("无申报记录")) {
                        msg = "您的企业本属期无申报记录，请核实！";
                        r.setMsg(msg);
                        return;
                    }

                    msg = msg.replaceAll("<kfpt>", "");
                    if (msg.matches("^[a-z,A-Z]{1}[\\s\\S]*$")) {
                        msg = "报告生成失败，请稍后再试！";
                        r.setMsg(msg);
                        return;
                    }

                    //未生成的也把提示语返回
                    r.setMsg(msg);
                }
            }

            // 生成成功,加结论
            if ("GENERATED".equals(r.getReportState())) {
                // 结论、测检得分
                RiskReportLevel risk = this.daoRepository.getRiskReportLevelExtMapper().getRiskReportLevelByKey(ywdlDm,
                        nsrsbh, formatSkssqq, formatSkssqz);
                if (null != risk) {
                    JieLunRespDTO jieLun = new JieLunRespDTO();
                    BeanUtils.copyProperties(risk, jieLun);

                    r.setJieLun(jieLun);
                }
            }
        });

        return riskReportListRespExtDTOList;
    }

}
